package de.lns.entities.turrets;

import java.nio.FloatBuffer;

import de.lns.entities.Entity;
import de.lns.entities.effect.Effect;
import de.lns.entities.mobs.Mob;
import de.lns.level.Circle;
import de.lns.level.Level;
import de.lns.level.Rectangle;
import de.lns.render.ModelFactory;
import de.lns.tick.UpdateThread;

public abstract class Turret extends Entity {
	
	protected static FloatBuffer mesh = ModelFactory.genRectMesh(45, 45, 45/2,45/2);
	protected int price=5;

	protected Bullet bullet;

	protected double attackspeed = 2;

	protected int shotsperattack = 1;

	protected double rangexy = 80;

	protected double rangez = 0;

	protected int timesincelastshot;

	/**
	 * 
	 * @param shotsperattack
	 *            The amount of Bullets a turret can shot in one attack.
	 */
	public void setShotsPerAttack(int shotsperattack) {
		this.shotsperattack = shotsperattack;
	}

	/**
	 * 
	 * @return The amount of shots per attack.
	 */
	public int getShotsPerAttack() {
		return shotsperattack;
	}

	/**
	 * 
	 * @return The Bullettype of this tower.
	 */
	public Bullet getBullet() {
		return bullet;
	}

	/**
	 * 
	 * @param bullet
	 *            The Bullet the tower should shoot.
	 */
	public void setBullet(Bullet bullet) {
		this.bullet = bullet;
	}

	/**
	 * 
	 * @return The attackspeed of this Tower in shots per second(default is 2).
	 */
	public double getAttackspeed() {
		return attackspeed;
	}

	/**
	 * 
	 * @param attackspeed
	 *            The Attackspeed in shots per second(default is 2).
	 */
	public void setAttackspeed(double attackspeed) {
		this.attackspeed = attackspeed;
	}

	/**
	 * 
	 * @return The range of the turret as radius(default is 5).
	 */
	public double getRangexy() {
		return rangexy;
	}

	/**
	 * 
	 * @param Rangexy
	 *            the range as radius(default is 5).
	 */
	public void setRangexy(double rangexy) {
		this.rangexy = rangexy;
	}

	/**
	 * 
	 * @return The zRange of this Turret (height)(default is 0).
	 */
	public double getRangez() {
		return rangez;
	}

	/**
	 * 
	 * @param rangez
	 *            The zRange of this turret (default is 0).
	 */
	public void setRangez(double rangez) {
		this.rangez = rangez;
	}

	/**
	 * 
	 * @param posX The XPosition of this turret.
	 * @param posY The YPosition of this turret.
	 * @param bullet The Bullettype of this turret.
	 * @param price	The price of this turret.
	 */
	public Turret(double posX, double posY, int price, double radius) {
		super(posX, posY);
		this.bullet = bullet;
		this.price=price;
		this.hitbox= new Circle(this, radius);
		
	}
	
	/**
	 * 
	 * @return The Price of this turret.
	 */

	public int getPrice() {
		return price;
	}
	/**
	 * 
	 * @param price How much this turret costs.
	 */
	public void setPrice(int price) {
		this.price = price;
	}

	/**
	 * 
	 * @param posX
	 *            XPosition of the turret.
	 * @param posY
	 *            YPosition of the turret.
	 * @param posZ
	 *            ZPosition of the turret.
	 * @param hitZ
	 *            Hitbox of this turret in height.
	 * @param bullet
	 *            Bullettype of this turret.
	 * @param price
	 * 			  Price of this turret.
	 */

	public Turret(double posX, double posY, double posZ, double hitZ,
			Bullet bullet) {
		super(posX, posY, posZ, hitZ);
		this.bullet = bullet;
		this.hitbox=new Rectangle(posX,posY,45,45);
	}

	/**
	 * Checks the Range of this turret and shoots if a target is in range.
	 */
	public void update() {
		timesincelastshot += UpdateThread.getDelta();
		if (timesincelastshot > 1000 / attackspeed) {
			int shotlimit = 0;
			for (Entity i : Effect.inrange(posX, posY, rangexy)) {
				if (i instanceof Mob && shotlimit<shotsperattack) {
					Bullet shot = createShot((Mob)i);
					Level.addEntity(shot);
					shotlimit+=1;
					timesincelastshot = 0;
				}
			}
		}
	}
	protected abstract Bullet createShot(Mob mob);
	public FloatBuffer getMesh() {
		return this.mesh;
	}

	@Override
	public FloatBuffer getMapping() {
		return this.map;
	}
	@Override
	public boolean alignRel() {
		return true;
	}
}
